package net.lzzy.practices.web.course;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import net.lzzy.practices.constants.ApiConstants;
import net.lzzy.practices.constants.Messages;
import net.lzzy.practices.entities.Applicant;
import net.lzzy.practices.entities.Course;
import net.lzzy.practices.service.ApplicantService;
import net.lzzy.practices.utils.StringUtils;
import net.lzzy.practices.web.models.ApiResult;
import net.lzzy.practices.web.models.ApplicantInfo;
import net.lzzy.practices.web.models.VmApplicant;
import net.lzzy.practices.web.models.VmCourse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

/**
 * @author 渊何
 */
@Api(tags = "注册相关业务")
@CrossOrigin
@RestController
@RequestMapping(ApiConstants.ROUTE_APPLICANT_ROOT)
public class ApplicantApiController {
    private final ApplicantService service;

    @Autowired
    public ApplicantApiController(ApplicantService service) {
        this.service = service;
    }

    @ApiOperation(value = "获取学生可申请注册课程", notes = "1.token(String)<br/>2.strCourseId(String)<br/>3.strStudentId(String)<br/>")
    @PostMapping(ApiConstants.ROUTE_APPLICANT_APPLY)
    public ApiResult apply(@RequestBody ApplicantInfo info) {
        String token = info.getToken();
        String strCourseId = info.getCourseId();
        String strStudentId = info.getStudentId();
        if (StringUtils.isEmpty(token) ||
                StringUtils.isEmpty(strStudentId) ||
                StringUtils.isEmpty(strCourseId)) {
            return new ApiResult(false, Messages.INCOMPLETE_INFO.toString(), null);
        }
        UUID studentId = UUID.fromString(strStudentId);
        UUID courseId = UUID.fromString(strCourseId);
        Applicant applicant = service.apply(studentId, courseId, token);
        if (applicant == null) {
            String msg = Messages.NO_PERMISSION + "或" + Messages.WRONG_ID;
            return new ApiResult(false, msg, null);
        }
        return new ApiResult(true, Messages.SUCCESS.toString(), applicant);
    }

    @ApiOperation(value = "教师查询已注册学生的课程", notes = "1.token(String)<br/>2.id(UUID)<br/>")
    @GetMapping(ApiConstants.ROUTE_APPLICANT_ENROLLED)
    public ApiResult getEnrolledCourses(@RequestParam String token, @RequestParam(name = "id") UUID studentId) {
        List<Applicant> applicants = service.getEnrolledApplicants(studentId);
        return transform(applicants);
    }

    @ApiOperation(value = "获取某学生正在申请的课程", notes = "1.token(String)<br/>2.id(UUID)<br/>")
    @GetMapping(ApiConstants.ROUTE_APPLICANT_APPLYING)
    public ApiResult getApplyingCourses(@RequestParam String token, @RequestParam(name = "id") UUID studentId) {
        List<Applicant> applicants = service.getApplyingApplicants(studentId);
        return transform(applicants);
    }

    @ApiOperation(value = "获取某学生已被驳回的课程", notes = "1.token(String)<br/>2.id(UUID)<br/>")
    @GetMapping(ApiConstants.ROUTE_APPLICANT_DECLINED)
    public ApiResult getDeclinedCourses(@RequestParam String token, @RequestParam(name = "id") UUID studentId) {
        List<Applicant> applicants = service.getDeclinedApplicants(studentId);
        return transform(applicants);
    }

    private ApiResult transform(List<Applicant> applicants) {
        if (applicants == null) {
            return new ApiResult(false, Messages.WRONG_ID.toString(), null);
        }
        List<VmApplicant> vmApplicants = new ArrayList<>();
        applicants.forEach(applicant -> vmApplicants.add(new VmApplicant(applicant)));
        return new ApiResult(true, applicants.size() + "", vmApplicants);
    }

    @ApiOperation(value = "教师通过学生申请的课程", notes = "1.token(String)<br/>2.id(UUID)<br/>")
    @PostMapping(ApiConstants.ROUTE_APPLICANT_APPROVE)
    public ApiResult approve(@RequestParam String token, @RequestParam(name = "id") UUID applicantId) {
        Applicant applicant = service.approve(applicantId, token);
        if (applicant == null) {
            String msg = Messages.NO_PERMISSION + "或" + Messages.WRONG_ID;
            return new ApiResult(false, msg, null);
        }
        return new ApiResult(true, Messages.SUCCESS.toString(), new VmApplicant(applicant));
    }

    @ApiOperation(value = "教师驳回学生申请的课程", notes = "1.token(String)<br/>2.id(UUID)<br/>")
    @PostMapping(ApiConstants.ROUTE_APPLICANT_DECLINE)
    public ApiResult decline(@RequestParam String token, @RequestParam(name = "id") UUID applicantId) {
        Applicant applicant = service.decline(applicantId, token);
        if (applicant == null) {
            String msg = Messages.NO_PERMISSION + "或" + Messages.WRONG_ID;
            return new ApiResult(false, msg, null);
        }
        return new ApiResult(true, Messages.SUCCESS.toString(), new VmApplicant(applicant));
    }

    @ApiOperation(value = "获取申请中的学生用户", notes = "1.token(String)<br/>2.id(UUID)<br/>")
    @GetMapping(ApiConstants.ROUTE_APPLICANT_TEACHER_APPLYING)
    public ApiResult getApplyingStudents(@RequestParam String token, @RequestParam(name = "id") UUID courseId) {
        List<Applicant> applicants = service.getApplyingStudents(courseId);
        return transform(applicants);
    }

    @ApiOperation("获取已登记的学生用户")
    @ApiImplicitParams({@ApiImplicitParam(name = "token", value = "token", dataType = "string", dataTypeClass = String.class, paramType = "query"),
            @ApiImplicitParam(name = "token", value = "token", dataType = "string", dataTypeClass = String.class, paramType = "query")})
    @GetMapping(ApiConstants.ROUTE_APPLICANT_TEACHER_ENROLLED)
    public ApiResult getEnrolledStudents(@RequestParam String token, @RequestParam(name = "id") UUID courseId) {
        List<Applicant> applicants = service.getEnrolledStudents(courseId);
        return transform(applicants);
    }

    @ApiOperation(value = "获取已拒绝的学生用户", notes = "1.token(String)<br/>2.id(UUID)<br/>")
    @GetMapping(ApiConstants.ROUTE_APPLICANT_TEACHER_DECLINED)
    public ApiResult getDeclinedStudents(@RequestParam String token, @RequestParam(name = "id") UUID courseId) {
        List<Applicant> applicants = service.getDeclinedStudents(courseId);
        return transform(applicants);
    }

    @ApiOperation(value = "删除已正式注册了某课程的学生", notes = "1.token(String)<br/>2.strCourseId(String)<br/>3.strStudentId(String)")
    @PostMapping(ApiConstants.ROUTE_APPLICANT_REMOVE)
    public ApiResult remove(@RequestBody ApplicantInfo info) {
        String token = info.getToken();
        String strCourseId = info.getCourseId();
        String strStudentId = info.getStudentId();
        if (StringUtils.isEmpty(token) ||
                StringUtils.isEmpty(strStudentId) ||
                StringUtils.isEmpty(strCourseId)) {
            return new ApiResult(false, Messages.INCOMPLETE_INFO.toString(), null);
        }
        UUID studentId = UUID.fromString(strStudentId);
        UUID courseId = UUID.fromString(strCourseId);
        Course course = service.removeStudent(studentId, courseId, token);
        if (course == null) {
            String msg = Messages.NO_PERMISSION + "或" + Messages.WRONG_ID;
            return new ApiResult(false, msg, null);
        }
        return new ApiResult(true, Messages.SUCCESS.toString(), VmCourse.create(course, true));
    }
}
